【アップデート】AWS X-Ray が AWS Lambda に対応しました(プレビュー)
こんにちは、藤本です。
日本時間2017/04/20(木) の『AWS Summit 2017 in San Francisco』で多くのアップデートが発表されました。弊社の AWS 関連ブログも賑わっております。
AWS X-Ray が General Available となりました。こちらは別のエントリがあります。AWS X-Ray に関しては下記エントリをご参照ください。
同時に発表された AWS Lambda 対応を試してみました。なお、本機能は既に設定・利用可能ですが、プレビューとなっています。本番環境でのご利用はご注意ください。
概要
今まで AWS Lambda のパフォーマンス解析を行う時、CloudWatch やログ出力の実装である程度可能でしたが、あくまでもある程度の解析しか行うことができませんでした。それが今回のアップデートにより、AWS X-Ray により AWS Lambda のパフォーマンス解析を詳細に行うことができるようになりました。AWS X-Ray サポートにより、Lambda ファンクションのオーバーヘッド、初期化(コールドスタート)、処理実行時間を計測できるようになり、AWS Lambda 側なのか、ソースコード側なのか、ボトルネックを特定できるようになりました。更にはソースコード内にトレースセグメントを埋め込むことでプログラム内のどこがボトルネックなのかも特定できるようになりました。
試してみた
それでは早速試してみましょう。API Gateway -> AWS Lambda -> DynamoDB の簡単なサンプルアプリケーションで試してみます。
IAM Role 作成
AWS Lambda に設定する IAM Role を作成します。X-Ray を利用するためには下記のポリシーが必要となります。
AWSXrayWriteOnlyAccess(Managed Policy も用意されています)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "xray:PutTraceSegments", "xray:PutTelemetryRecords" ], "Resource": [ "*" ] } ] }
Lambda Function 作成
Lambda Function を作成します。今回は Node.js のサンプルを利用します。AWS Lambda のページから Create a Lambda Function をクリックします。
Blueprint の microservice-http-endpoint を利用します。
Security を Open にして、次へ
適当な Name、作成した IAM Role を入力します。で、Advanced settings に X-Ray の設定項目が追加されています。Enable active tracing をチェックするだけで AWS X-Ray が有効になります。
確認画面がチェックボックスw Create function をクリックします。
これで、API Gateway と X-Ray が有効化された Labmda Function が作成されます。
DynamoDB テーブルの作成
動作確認用の DynamoDB テーブルを作成します。
適当にテーブル名をxray
、プライマリーキーをid
に設定しました。
動作確認
それでは動作を見てみましょう。
API Gateway のエンドポイントにリクエストを送ってみます。
$ curl -XPOST https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/x-ray-test -d '{ "TableName" : "xray", "Item": { "id" : "1", "name": "shinji" }}' {}
X-Ray のサービスマップを確認してみます。
Lambda サービス、Lambda Function の 2つのサービスが表示されています。意図せず、正常リクエストと、エラーリクエストを発生させました。ステータスの割合がパッと見で分かるようになっています。
次に Trace でリクエスト単位の詳細を見てみます。
リクエスト単位で表示されています。リクエストをクリックして詳細を見てみます。
サービス全体で 1.1秒。初回実行ではないので、初期化処理は 1ミリ秒とほぼかかっていません。どこの処理時間がかかっているのか分かりやすい!
トレースセグメント
次に X-Ray の SDK を利用して、ソースコードにトレースセグメントを埋め込んで特定の処理時間を取得します。今回は DynamoDB へのアクセス時間を取得します。
X-Ray の SDK を利用するためには SDK を npm でインストールする必要があります。Lambda Function の標準コンテナに含めてほしいなぁ。と思ったけど、SDK の追加容量分だけ初期化処理時間が微量とは言え増えるからダメか。
$ npm install aws-xray-sdk : └─┬ aws-xray-sdk@1.1.0 ├─┬ aws-xray-sdk-core@1.1.0 │ ├─┬ continuation-local-storage@3.2.0 │ │ ├─┬ async-listener@0.6.5 │ │ │ └── shimmer@1.1.0 │ │ └─┬ emitter-listener@1.0.1 │ │ └── shimmer@1.0.0 │ ├── moment@2.18.1 │ ├── semver@5.3.0 │ ├── underscore@1.8.3 │ └─┬ winston@2.3.1 │ ├── async@1.0.0 │ ├── colors@1.0.3 │ ├── cycle@1.0.3 │ ├── eyes@0.1.8 │ ├── isstream@0.1.2 │ └── stack-trace@0.0.9 ├── aws-xray-sdk-express@1.1.0 ├── aws-xray-sdk-mysql@1.1.0 ├── aws-xray-sdk-postgres@1.1.0 └── pkginfo@0.4.0 :
ソースコードにトレースセグメントを埋め込んで、Zip 化して、Lambda Function にアップロードします。
$ vi index.js 下記を変更 ==================== const dynamo = new doc.DynamoDB(); ==================== const AWSXRay = require('aws-xray-sdk-core'); const dynamo = AWSXRay.captureAWSClient(new doc.DynamoDB()); ==================== $ zip -r lambda.zip index.js
今度は先ほど登録したデータを取得します。
$ curl "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/x-ray-test?TableName=xray" {"Items":[{"id":"1","name":"shinji"}],"Count":1,"ScannedCount":1}
X−Ray のサービスマップを確認します。
サービスマップに DynamoDB が追加されました。
Trace でリクエストの詳細を見てみます。
詳細でも DynamoDB の処理が追加されましたね!これでどこにどれだけの処理を費やしているのか簡単に確認できます!
まとめ
いかがでしたでしょうか? AWS Lambda はサーバーレスということもあり、解析を十分に行うことができませんでした。EC2 であれば導入可能な APM の DataDog や New Relic も AWS Lambda には導入できません。AWS X-Ray が AWS Lambda の解析に役立つのは間違いありません。GA リリースが待ち遠しいですね!